package com.game.logic.fighting.attrs;

import com.coment.cfg.luban.constant.AIDCFG;
import com.coment.message.BloodReturningMessage;
import com.coment.po.roles.Roles;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/// 战斗逻辑
@Slf4j
public class FightingLogic {
    /// 零值常量
    private static final double ZERO = 0.0;
    /// 毫秒转秒的除数
    private static final double MS_TO_SECONDS = 1000.0;
    /// 复活时间（秒）
    private static final int RESURRECTION_TIME_SECONDS = 3;
    /// 回血冷却时间（毫秒）
    private static final long BLOOD_RETURN_COOLDOWN_MS = 10_000L;

    // ----------------------------- 战斗判定
    public static boolean canAttack(Roles roles) {
        long currentTimeMillis = System.currentTimeMillis();
        Map<Integer, Double> attribute = roles.rolePanel.getAttribute();
        double lastAtkTime1 = attribute.getOrDefault(AIDCFG.lastAtkTime1, 0d);
        double atkSpeed = attribute.get(AIDCFG.atkSpeed); //1s 多少次

        double interval;
        if (atkSpeed == 0) {
            interval = 0;
        } else {
            interval = 1000 / atkSpeed;
        }
        double canAttackTime = lastAtkTime1 + interval;

        double distanceFromNextAttackTime = canAttackTime - currentTimeMillis;
        boolean b = distanceFromNextAttackTime < 0;
        if (!b) {
            log.debug("{}-{}距离下次可攻击时间 {}", roles.id, roles.cardId, distanceFromNextAttackTime);
        }
        return b;
    }

    public static boolean isCrit(Roles atk, Roles def) {
        Map<Integer, Double> atkAttrs = atk.rolePanel.getAttribute();
        Map<Integer, Double> defAttrs = def.rolePanel.getAttribute();
        double criticalHitRate = atkAttrs.get(AIDCFG.criticalHitRate);
        double antiCriticalHitRate = defAttrs.get(AIDCFG.antiCriticalHitRate);
        double critRate = criticalHitRate - antiCriticalHitRate;

        boolean res;
        if (critRate <= 0.0D) {
            res = false;
        } else {
            double randomValue = Math.random();
            res = critRate > randomValue;
        }
        log.debug("暴击判定: 结果 {} |有效暴击{} = 暴击率{} - 防御方抗爆率{}", res, critRate, criticalHitRate, antiCriticalHitRate);
        return res;
    }

    /**
     * 尝试回血
     */
    public static BloodReturningMessage tryBloodReturning(Roles roles) {
        // 检查战斗面板是否存在且有属性
        if (roles.rolePanel.fightPanel == null || roles.rolePanel.fightPanel.getValue().isEmpty()) {
            return null;
        }
        String rolesId = roles.getId();

        // 检查角色是否死亡
        Double deathTime = roles.rolePanel.statusPanel.getValue().get(AIDCFG.deathTime);
        if (deathTime != null && !deathTime.equals(ZERO)) {
            return null;
        }

        // 检查血量是否需要回复
        double currentHp = roles.rolePanel.fightPanel.fight.getOrDefault(AIDCFG.hp, 0.0d);
        if (currentHp >= ZERO) {
            return null;
        }

        // 检查回血冷却时间
        Double lastHpReplyTime = roles.rolePanel.getAttribute().get(AIDCFG.lastHpReplyTime);
        double currentTime = System.currentTimeMillis();
        double intervalTime = currentTime - lastHpReplyTime;

        if (intervalTime < BLOOD_RETURN_COOLDOWN_MS) {
            double remainingCooldown = (BLOOD_RETURN_COOLDOWN_MS - intervalTime) / MS_TO_SECONDS;
//            log.info("用户[{}]角色[{}]已回复过血,下次回血需要{}秒", userInfoId, cardId, remainingCooldown);
            return null;
        }

        // 计算并应用回血效果
        Double bloodReturning = roles.rolePanel.getAttribute().get(AIDCFG.hpReply);
        double newHp = Math.min(currentHp + bloodReturning, ZERO);
        double healedAmount = newHp - currentHp;

        roles.rolePanel.fightPanel.fight.put(
                AIDCFG.hp,
                newHp
        );
        roles.rolePanel.statusPanel.status.put(
                AIDCFG.lastHpReplyTime,
                currentTime
        );

        BloodReturningMessage bloodReturningMessage = new BloodReturningMessage();
        bloodReturningMessage.rolesId = rolesId;
        bloodReturningMessage.addValue = healedAmount;
        bloodReturningMessage.hp = roles.rolePanel.getAttribute().get(AIDCFG.hp);
        return bloodReturningMessage;
    }


    /// 受到伤害
    public static void beHarmed(Roles updateRoles, double hurtValue) {
        if (hurtValue == 0) {
            return;
        }
        // 判空保护
        if (
                updateRoles.rolePanel == null ||
                        updateRoles.rolePanel.fightPanel == null ||
                        updateRoles.rolePanel.fightPanel.fight == null
        ) {
            log.error("战斗面板未初始化");
            return;
        }

        Double v = updateRoles.rolePanel.getAttribute().get(AIDCFG.hp);
        if (v <= 0) {
            updateRoles.rolePanel.statusPanel.status.put(AIDCFG.deathTime, (double) System.currentTimeMillis());
            log.debug("角色{}已死亡", updateRoles.getId());
            return;
        }

        Double shield = updateRoles.rolePanel.getAttribute().getOrDefault(AIDCFG.shield, 0D);

        if (shield > 0) {
            if (shield < hurtValue) {
                hurtValue -= shield;
                log.debug("角色{}的护盾抵消了共计{}点伤害", updateRoles.getId(), shield);
                updateRoles.rolePanel.fightPanel.fight.merge(AIDCFG.shield, -shield, Double::sum);
            } else {
                log.debug("角色{}的护盾抵消所有伤害共计{}", updateRoles.getId(), hurtValue);
                updateRoles.rolePanel.fightPanel.fight.merge(AIDCFG.shield, -hurtValue, Double::sum);
                return;
            }
        }

        updateRoles.rolePanel.fightPanel.fight.merge(AIDCFG.hp, -hurtValue, Double::sum);
        if (updateRoles.rolePanel.getAttribute().get(AIDCFG.hp) < 0) {
            updateRoles.rolePanel.statusPanel.status.put(AIDCFG.deathTime, (double) System.currentTimeMillis());
            log.debug("角色{}已死亡", updateRoles.getId());
        }
    }

}
